<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // Function.prototype.myCall = function (context, ...args) {//绑定并执行
        //     //执行函数
        //     var fn = this;
        //     context.fn = fn;
        //     context.fn(...args);
        //     delete context.fn
        // }

       


        let obj = {
            name: "Hydra",
            sayHello(content = "你好") {
                console.log(`${this.name}说：“${content}”`)
            },
            sayBye(word1,word2) {
                console.log(`${this.name}说：“${word1},${word2}”`)
            }
        }

        let lyx = {
            name: "刘煜鑫"
        }

        window.name = "window";
        let fun = obj.sayHello;
        fun();

        obj.sayHello();

        obj.sayHello.call(lyx,"吃屎");
        obj.sayHello.apply(lyx,["滚蛋"]);

        // bind得到函数对象
        let f = obj.sayHello.bind(lyx,"喝尿");
        f();


        console.log(Function.prototype.call);


        Function.prototype.myCall = function(obj,...args) {
            // this是当前函数，赋值给一个变量
            let fn = this;

            // 把obj添加一个属性为当前函数
            obj.fn = fn;
            // 使用obj调用函数，这样函数内部的this就变为了obj
            obj.fn(...args);

            // 删除obj.fn属性，外部看上就像obj没有过fn属性一样
            delete obj.fn
        }

        obj.sayHello.myCall(lyx,"喝水");

        Function.prototype.myBind = function (obj,...args) {//绑定返回新的执行函数
            // 判断调用者是不是函数
            if (typeof this != 'function') {
                throw new Error("Error")
            }
            var _this = this;//保存一下当前的调用者  
            return function F() {
                return _this.call(obj,...args)
            }
        } 

        obj.sayBye.myCall(lyx,"再见","对对对");
        let f2 = obj.sayBye.myBind(lyx,"再见","打老子");
        f2();

    </script>
</body>

</html>